"""
用户账户相关操作
"""
import logging

from django.urls import reverse
from django.conf import settings
from django.shortcuts import redirect
from django.contrib.auth.models import User
from django.middleware.csrf import get_token
from django.views.generic import TemplateView, FormView
from django.utils.module_loading import import_string

from oracle import models
from oracle.base import baseview
from oracle.utils.encryption import gen_md5
from oracle.forms.user import UserLoginForm
from oracle.base.tools import get_random_string
from oracle.service.init_handler import init_handler

logger = logging.getLogger(__name__)


class LoginHandle(baseview.BaseMixin, FormView):
    """
    用户登录操作
    """
    template_name = 'oracle/login.html'

    def get(self, request, *args, **kwargs):
        """
        登陆 get 方法
        :param request:
        :param args:
        :param kwargs:
        :return:
        """

        # 内部渲染方法
        def method(r, t, d):
            return super(LoginHandle, self).get(r, data=d, *args, **kwargs)

        # 外部渲染返回参数
        status = 'login_success'
        # csrf token主动获取
        csrf_token = get_token(request)
        data = {'csrf_token': csrf_token}
        msg = "请输入用户名密码进行登陆"
        return baseview.render_handler(request, status, method, data=data, msg=msg, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        """
        登陆操作 确认用户名和密码是否匹配
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        # TODO 如果二次开发修改匹配逻辑
        # 获取用户名、密码
        username = self.request.POST.get('username')
        pwd = self.request.POST.get('password')
        password = gen_md5(pwd)
        # 如果有单独的认证，需要提前导入单独认证的权限组、角色等配置为用户，此后依旧通过本RBAC进行权限确认
        # 获取用户的queryset
        user_info = import_string(settings.SERVICE_USER_MODEL_CLASS)
        current_user = user_info.objects.filter(username=username, password=password, status=0).first()

        if current_user:
            # 用户权限以及菜单初始化
            user_info = {
                "show_name": current_user.username,
                "show_detail": current_user.detail,
                "show_avatar": current_user.avatar,
            }
            result = init_handler(self.request, [current_user, ], user_info)
            if result:
                # 外部渲染信息
                status = 'login_success'

                # 内部渲染信息
                def method(r, t, d):
                    return redirect(reverse("index"))
            else:
                # 初始化有问题进行提示
                status = 'init_error'

                def method(r, t, d):
                    return super(LoginHandle, self).get(r, data=d, *args, **kwargs)
        else:
            # 没有对应用户设置错误信息
            status = 'user_not_exist'
            msg = 'username or password wrong!'
            kwargs["msg"] = msg

            def method(r, t, d):
                return super(LoginHandle, self).get(r, data=d, *args, **kwargs)

        return baseview.render_handler(request, status, method, *args, **kwargs)

    def get_form_class(self):
        return UserLoginForm

    def get_context_data(self, **kwargs):
        data = kwargs.setdefault("data", {})
        data.update({
            "login_logo_name": "",
            "login_title": "",
            "login_subtitle": "",
        })
        return super(LoginHandle, self).get_context_data(**kwargs)


class LogoutHandle(baseview.BaseMixin, TemplateView):
    """
    用户登出操作
    """
    template_name = 'oracle/login.html'

    def get(self, request, *args, **kwargs):
        return self.render_handler(*args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.render_handler(*args, **kwargs)

    def render_handler(self, *args, **kwargs):
        self.request.session.flush()

        def method(r, t, d):
            return redirect(reverse("login"))

        # 外部渲染信息
        status = 'logout_success'
        return baseview.render_handler(self.request, status, method, *args, **kwargs)


class IndexHandle(baseview.BaseMixin, TemplateView):
    """
    内部首页页面
    """
    template_name = 'oracle/index.html'

    def get(self, request, *args, **kwargs):
        """
        首页 get 方法
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        data = dict()

        # 内部渲染方法
        def method(r, t, d):
            kwargs.update(d)
            return super(IndexHandle, self).get(r, *args, **kwargs)

        # 外部渲染返回参数
        status = 'success'
        baseview.get_context_data(request, logger, data)
        return baseview.render_handler(request, status, method, data=data, *args, **kwargs)


class InitDB(baseview.BaseMixin, TemplateView):
    """
    初始化rbac权限数据库
    """
    # TODO: 提示页面更新
    template_name = 'oracle/init_db.html'

    def get(self, request, *args, **kwargs):
        if not User.objects.filter(username='gideon'):
            User.objects.create_superuser('gideon', 'gideon@watchtower.com', 'Arron01;')
            # print('superuser is created!')

        from oracle.views.init_db_items import permission_list, role_list, menu_list, icon_list
        # 权限登记
        for item in permission_list:
            if not models.OPermission.objects.filter(id=item[0]):
                key = get_random_string(24)
                key = f"{key[:13]}{item[0]}{key[13:]}"
                models.OPermission.objects.create(id=item[0], title=item[1], url=item[2], name=item[3], key=key)

        # 角色登记
        for item in role_list:
            if not models.ORole.objects.filter(id=item[0]):
                key = get_random_string(24)
                key = f"{key[:13]}{item[0]}{key[13:]}"
                r = models.ORole.objects.create(id=item[0], title=item[1], key=key)
                for i in item[2]:
                    r.permissions.add(models.OPermission.objects.get(id=i))

        # 菜单登记
        for item in menu_list:
            if not models.OMenu.objects.filter(id=item[0]):
                key = get_random_string(24)
                key = f"{key[:13]}{item[0]}{key[13:]}"
                models.OMenu.objects.create(
                    id=item[0],
                    title=item[1],
                    menu_icon=item[2],
                    parent=models.OMenu.objects.get(id=item[3]) if item[3] else item[3],
                    link_to_permission=models.OPermission.objects.get(id=item[4]) if item[4] else item[4],
                    menu_inner=models.OMenu.objects.get(id=item[5]) if item[5] else item[5],
                    key=key
                )

        # 图标登记
        for item in icon_list:
            if not models.OIcon.objects.filter(id=item[0]):
                key = get_random_string(24)
                key = f"{key[:13]}{item[0]}{key[13:]}"
                models.OIcon.objects.create(
                    id=item[0],
                    title=item[1],
                    icon_class=item[2],
                    category=models.OIcon.objects.get(id=item[3]) if item[3] else item[3],
                    key=key
                )

        def method(r, t, d):
            return super(InitDB, self).get(r, data=d, *args, **kwargs)

        # 外部渲染信息
        status = 'db_init_success'
        return baseview.render_handler(request, status, method, *args, **kwargs)
